/*!
\copyright  Copyright (c) 2023 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file       a2dp_profile_event_send.c
\brief      The sending of events from the a2dp profile using the Event Bus
*/

#include "a2dp_profile_event_send.h"
#include "a2dp_profile_channel_event_spec.h"
#include "a2dp_profile_codec_handler.h"

#include "av_seids.h"

#include "event_bus_publish.h"

#include <logging.h>


static void a2dpProfile_EventBusSend(a2dp_profile_event_t event, void * data, uint16 data_size)
{
    EventBus_Publish(EVENT_BUS_CHANNEL_A2DP_PROFILE, event, data, data_size);
}

static uint8 a2dpProfile_EventSendConvertSeidToCodecType(uint8 seid)
{
    uint8 codec_type = a2dp_profile_event_codec_type_invalid;
    
    switch (seid)
    {
        case AV_SEID_INVALID:
            codec_type = a2dp_profile_event_codec_type_invalid;
            break;
        case AV_SEID_SBC_SRC: 
        case AV_SEID_SBC_SNK:
        case AV_SEID_SBC_MONO_TWS_SRC:
        case AV_SEID_SBC_MONO_TWS_SNK:
            codec_type = a2dp_profile_event_codec_type_sbc;
            break;
            
        case AV_SEID_AAC_SNK:
        case AV_SEID_AAC_STEREO_TWS_SRC:
        case AV_SEID_AAC_STEREO_TWS_SNK:
            codec_type = a2dp_profile_event_codec_type_aac;
            break;
            
        case AV_SEID_APTX_CLASSIC_SRC:
        case AV_SEID_APTX_SNK:
        case AV_SEID_APTX_MONO_TWS_SRC:
        case AV_SEID_APTX_MONO_TWS_SNK:
            codec_type = a2dp_profile_event_codec_type_aptx;
            break;
            
        case AV_SEID_APTXHD_SRC:
        case AV_SEID_APTXHD_SNK:
            codec_type = a2dp_profile_event_codec_type_aptx_hd;
            break;
            
        case AV_SEID_APTX_ADAPTIVE_SRC:
        case AV_SEID_APTX_ADAPTIVE_SNK:
        case AV_SEID_APTX_ADAPTIVE_TWS_SRC:
        case AV_SEID_APTX_ADAPTIVE_TWS_SNK:
            codec_type = a2dp_profile_event_codec_type_aptx_adaptive;
            break;
            
        default:
            break;
    }
    
    return codec_type;
}


void A2dpProfile_EventSendAvOpen(avInstanceTaskData *theInst)
{
    a2dp_profile_event_a2dp_open_t event = {0};
    event.addr = theInst->bd_addr;
    
    DEBUG_LOG("A2dpProfile_EventSendAvOpen");
    
    a2dpProfile_EventBusSend(a2dp_profile_event_a2dp_open, &event, sizeof(a2dp_profile_event_a2dp_open_t));
}

void A2dpProfile_EventSendAvCodecConfigured(avInstanceTaskData *theInst)
{
    a2dp_codec_settings *codec_settings = PanicNull(appA2dpGetCodecAudioParams(theInst));
    a2dp_profile_event_a2dp_codec_configured_t event = {0};
    event.addr = theInst->bd_addr;
    event.codec_type = a2dpProfile_EventSendConvertSeidToCodecType(theInst->a2dp.local_sep.seid);
    if(codec_settings!=NULL)
    {
        event.sample_rate = codec_settings->rate;
        event.sample_bit_depth = codec_settings->sample_bit_depth;
        free(codec_settings);
    }

    DEBUG_LOG("A2dpProfile_EventSendAvCodecConfigured seid=%d, codec_type=enum:a2dp_profile_event_codec_type_t:%d, sample_rate=%u, sample_bit_depth=%u",
                theInst->a2dp.local_sep.seid, event.codec_type, event.sample_rate, event.sample_bit_depth);

    a2dpProfile_EventBusSend(a2dp_profile_event_a2dp_codec_configured, &event, sizeof(event));
}

void A2dpProfile_EventSendAvClose(avInstanceTaskData *theInst)
{
    if (theInst->a2dp.local_sep.seid != AV_SEID_INVALID)
    {
        a2dp_profile_event_a2dp_close_t event = {0};
        event.addr = theInst->bd_addr;
        
        DEBUG_LOG("A2dpProfile_EventSendAvClose");
        
        a2dpProfile_EventBusSend(a2dp_profile_event_a2dp_close, &event, sizeof(a2dp_profile_event_a2dp_close_t));
    }
    else
    {
        DEBUG_LOG("A2dpProfile_EventSendAvClose seid invalid");
    }
}

void A2dpProfile_EventSendAvStreaming(avInstanceTaskData *theInst)
{
    a2dp_profile_event_a2dp_streaming_t event = {0};
    event.addr = theInst->bd_addr;
    
    DEBUG_LOG("A2dpProfile_EventSendAvStreaming");
    
    a2dpProfile_EventBusSend(a2dp_profile_event_a2dp_streaming, &event, sizeof(a2dp_profile_event_a2dp_streaming_t));
}

void A2dpProfile_EventSendAvSuspended(avInstanceTaskData *theInst)
{
    a2dp_profile_event_a2dp_suspended_t event = {0};
    event.addr = theInst->bd_addr;
    
    DEBUG_LOG("A2dpProfile_EventSendAvSuspended");
    
    a2dpProfile_EventBusSend(a2dp_profile_event_a2dp_suspended, &event, sizeof(a2dp_profile_event_a2dp_suspended_t));
}

